package com.explorx.sns.puma.im.core.controller;

import com.explorex.puma.common.enums.ConvTypeEnum;
import com.explorx.sns.puma.im.core.chat.model.CreateConvModel;
import com.explorx.sns.puma.im.core.common.exceptions.BizException;
import com.explorx.sns.puma.im.core.chat.ConversationService;
import com.explorx.sns.puma.im.core.chat.MessageService;
import com.explorx.sns.puma.im.core.chat.UserRelationService;
import com.explorx.sns.puma.im.core.chat.consts.CheckPrivilegeResultEnum;
import com.explorx.sns.puma.im.core.chat.consts.UserRelationEnum;
import com.explorx.sns.puma.im.core.chat.model.ConversationModel;
import com.explorx.sns.puma.im.core.chat.model.MessageModel;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

@Slf4j
@DubboService(version = "1.0.0")
@Service
public class MessageGatewayServiceImpl implements MessageGatewayService{

    @Resource
    private MessageService messageService;

    @Resource
    private ConversationService conversationService;

    @Resource
    private UserRelationService userRelationService;

    @Override
    public void saveMessage(MessageModel messageModel) {

        if(isFirstChat(messageModel)){
            final UserRelationEnum userRelationEnum = userRelationService.queryUserRelation(messageModel.getSenderId(), messageModel.getPartnerId());
            // todo 陌生人不可用相互发消息，或者只能发送有限数量的消息
            if(userRelationEnum==UserRelationEnum.Stranger){
                return;
            }else {
                final Long conversation = conversationService.createConversation(CreateConvModel.builder()
                        .senderId(messageModel.getSenderId())
                        .convType(ConvTypeEnum.GROUP.getValue())
                        .partnerId(messageModel.getPartnerId())
                        .build());
            }
        }else {
            final ConversationModel userConvByUserIdAndCid = conversationService.getUserConvByUserIdAndCid(messageModel.getSenderId(), messageModel.getCid());
            if(userConvByUserIdAndCid==null){
                log.warn("user not in cid, req={}",messageModel.toString());
                return;
            }
        }
        messageService.saveMessage(messageModel);
    }

    @Override
    public void revokeMessage(Long senderId, Long cid, Long msgId) {
        //检查 操作权限
        try {
            Preconditions.checkArgument(Objects.nonNull(senderId));
            Preconditions.checkArgument(Objects.nonNull(cid));
            Preconditions.checkArgument(Objects.nonNull(msgId));
            checkPrivilege(senderId,cid,msgId);
            messageService.revokeMessage(cid, msgId);
        }catch (IllegalArgumentException e){
            log.error("revokeMessage failed senderId={},cid={},msgId={}",senderId,cid,msgId,e);
        }catch (Exception e){
            log.error("revokeMessage exception senderId={},cid={},msgId={}",senderId,cid,msgId,e);
        }
    }

    private void checkPrivilege(Long senderId, Long cid, Long msgId) throws BizException {
        final ConversationModel userConvByUserIdAndCid = conversationService.getUserConvByUserIdAndCid(senderId, cid);
        if(userConvByUserIdAndCid==null){
            log.warn("不在会话内，没有操作权限 sender={},cid={},msgId={}",senderId,cid,msgId);
            throw  new BizException(CheckPrivilegeResultEnum.SENDER_NOT_IN_CONV);
        }
        final MessageModel messageModel = messageService.queryConvMessage(cid, msgId);
        if(messageModel==null){
            log.warn("没有创建消息，没有操作权限 sender={},cid={},msgId={}",senderId,cid,msgId);
            throw new BizException(CheckPrivilegeResultEnum.MSG_NOT_IN_CONV);
        }
    }

    @Override
    public void deleteMessage(Long senderId, Long cid, Long msgId) {
        //检查 操作权限
        try {
            Preconditions.checkArgument(Objects.nonNull(senderId));
            Preconditions.checkArgument(Objects.nonNull(cid));
            Preconditions.checkArgument(Objects.nonNull(msgId));
            checkPrivilege(senderId,cid,msgId);
            checkPrivilege(senderId,cid,msgId);
            messageService.deleteMessage(senderId,cid,msgId);
        }catch (IllegalArgumentException e){
            log.error("deleteMessage failed senderId={},cid={},msgId={}",senderId,cid,msgId,e);
        }catch (Exception e){
            log.error("deleteMessage failed senderId={},cid={},msgId={}",senderId,cid,msgId,e);
        }
    }

    private boolean isFirstChat(MessageModel messageModel){
        return messageModel.getCid()==null
                && messageModel.getSenderId()!=null
                && messageModel.getPartnerId()!=null;
    }
}
